<template>
  <a-layout-header class="p-workbench-main__header">
    <a-flex justify="space-between" align="center" style="height: 100%">
      <a-button
        type="primary"
        :icon="h(PlusOutlined)"
        @click="createWhiteBoard"
        :loading="createBtnLoading"
      >
        新建白板
      </a-button>
      <a-row align="middle" :gutter="24">
        <a-col>
          <a-input
            v-model:value="searchName"
            placeholder="搜索白板"
            allowClear
            @pressEnter="search"
            @change="search"
          >
            <template #prefix>
              <SearchOutlined class="color-grey" />
            </template>
          </a-input>
        </a-col>
        <a-col>
          <a-dropdown :trigger="['click']">
            <a-avatar
              :src="avatarUrl"
              size="large"
              class="p-workbench-main__header-avatar"
            />
            <template #overlay>
              <a-menu>
                <a-card
                  :bordered="false"
                  style="width: 250px; box-shadow: 0 0 0 0"
                  size="small"
                >
                  <a-card-meta :title="nickname" :description="account">
                    <template #avatar>
                      <a-avatar :src="avatarUrl" size="large" />
                    </template>
                  </a-card-meta>
                </a-card>
                <a-menu-divider />
                <a-menu-item
                  @click="() => (accountInfoModal.infoModalVisible = true)"
                >
                  <template #icon>
                    <SettingOutlined />
                  </template>
                  账号设置
                </a-menu-item>
                <a-menu-item @click="logoutAccount">
                  <template #icon>
                    <LogoutOutlined />
                  </template>
                  退出登录
                </a-menu-item>
              </a-menu>
            </template>
          </a-dropdown>
        </a-col>
      </a-row>
    </a-flex>
  </a-layout-header>
  <a-modal
    v-model:open="accountInfoModal.infoModalVisible"
    title="账号设置"
    centered
    :width="900"
    :maskClosable="false"
    :footer="null"
    :body-style="{ padding: '24px 80px' }"
    :mask-style="{ backgroundColor: 'rgba(255,255,255,0.7)' }"
    @cancel="() => (accountInfoModal.infoModalVisible = false)"
  >
    <a-descriptions
      :colon="false"
      :column="1"
      :labelStyle="{ width: '10rem', alignItems: 'center', height: '3rem' }"
      :contentStyle="{ width: '100%', display: 'block', height: '3rem' }"
    >
      <a-descriptions-item label="头像">
        <a-flex justify="space-between" align="center" style="height: 100%">
          <a-avatar size="large" :src="avatarUrl"></a-avatar>
          <a-upload
            name="file"
            :max-count="1"
            :customRequest="uploadNewAvatar"
            :showUploadList="false"
          >
            <span style="color: #9a9a9a; margin: 0 15px">
              支持jpg、png格式，大小不超过4MB
            </span>
            <a-button>
              <template #icon>
                <UploadOutlined></UploadOutlined>
              </template>
              上传新头像
            </a-button>
          </a-upload>
        </a-flex>
      </a-descriptions-item>
      <a-descriptions-item label="昵称">
        <a-flex justify="space-between" align="center" style="height: 100%">
          <a-flex v-if="accountInfoModal.isUpdatingNickname" gap="small">
            <a-input ref="nickNameInputRef" v-model:value="nickname" />
            <a-button
              type="link"
              :icon="h(CheckOutlined)"
              @click="confirmUpdateNickname"
            ></a-button>
          </a-flex>
          <span v-else>{{ nickname }}</span>
          <a-button
            @click="cancelUpdate"
            v-if="accountInfoModal.isUpdatingNickname"
          >
            取消修改
          </a-button>
          <a-button @click="updateNickname" v-else>修改</a-button>
        </a-flex>
      </a-descriptions-item>
      <a-descriptions-item label="手机号码">
        <a-flex justify="space-between" align="center" style="height: 100%">
          <span>{{ account }}</span>
          <a-button @click="openEditModal('修改手机号码')">修改</a-button>
        </a-flex>
      </a-descriptions-item>
      <a-descriptions-item label="密码">
        <a-flex justify="space-between" align="center" style="height: 100%">
          <span>********</span>
          <a-button @click="openEditModal('设置密码')">修改</a-button>
        </a-flex>
      </a-descriptions-item>
    </a-descriptions>
  </a-modal>
  <a-modal
    v-model:open="editModalData.modalVisible"
    :title="editModalData.modalTitle"
    :width="500"
    :body-style="{
      padding:
        editModalData.modalTitle === '设置密码' ? '24px' : '24px 24px 0 24px',
    }"
    :mask-style="{ backgroundColor: 'rgba(255,255,255,0.7)' }"
    :maskClosable="false"
    @cancel="cancelEdit"
  >
    <template v-if="editModalData.modalTitle === '设置密码'">
      <a-form
        ref="pwFormRef"
        :model="editModalData.pwFormData"
        layout="vertical"
        :rules="pwFormRules"
      >
        <a-form-item label="输入新密码" name="newPassword">
          <a-input-password
            v-model:value="editModalData.pwFormData.newPassword"
          />
        </a-form-item>
        <a-form-item label="确认您的新密码" name="checkPassword">
          <a-input-password
            v-model:value="editModalData.pwFormData.checkPassword"
          />
        </a-form-item>
        <a-button type="primary" block @click="updatePassword">
          设置密码
        </a-button>
      </a-form>
    </template>
    <template v-else>
      <a-form
        :model="editModalData.phoneFormData"
        :rules="phoneFormRules"
        ref="phoneFormRef"
      >
        <a-form-item name="newPhoneNum">
          <a-input-group compact size="large">
            <a-form-item-rest>
              <a-select
                v-model:value="editModalData.phoneFormData.prefix"
                style="width: 40%"
              >
                <a-select-option value="86">+86（中国）</a-select-option>
              </a-select>
            </a-form-item-rest>
            <a-input
              v-model:value="editModalData.phoneFormData.newPhoneNum"
              placeholder="新手机号码"
              style="width: 60%"
            />
          </a-input-group>
        </a-form-item>
        <a-form-item name="verifyCode">
          <a-input-group compact size="large">
            <a-input
              v-model:value="editModalData.phoneFormData.verifyCode"
              placeholder="验证码"
              style="width: 60%"
            />
            <a-button
              style="width: 40%"
              @click="getVerifyCode"
              :disabled="verifyCodeBtn.disabled"
              :loading="verifyCodeBtn.loading"
            >
              <span style="font-size: 0.8rem">
                {{ verifyCodeBtn.text }}
              </span>
            </a-button>
          </a-input-group>
        </a-form-item>
      </a-form>
    </template>
    <template #footer>
      <template v-if="editModalData.modalTitle === '修改手机号码'">
        <a-button @click="cancelEdit">取消</a-button>
        <a-button type="primary" @click="confirmUpdatePhone">确定</a-button>
      </template>
    </template>
  </a-modal>
</template>

<script setup lang="ts">
import { h, onMounted, reactive, ref, watchEffect } from 'vue';
import {
  PlusOutlined,
  SearchOutlined,
  SettingOutlined,
  LogoutOutlined,
  UploadOutlined,
  CheckOutlined,
} from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';
import operateWhiteBoard from '@/apis/operate-white-board.ts';
import { useTeamStore, useBoardStore, useAccountStore } from '@/store/index.ts';
import { router } from '@/router';
import operateAccount from '@/apis/operate-account.ts';
import { storeToRefs } from 'pinia';
import { Rule } from 'ant-design-vue/es/form';
import {
  validatePassword,
  validateVerifyCode,
  validateUsername,
} from '@/utils/FormRules.ts';

const teamStore = useTeamStore();
const boardStore = useBoardStore();
const accountStore = useAccountStore();
const { account, nickname, avatarUrl } = storeToRefs(accountStore);
const {
  getAccountInfo,
  uploadImg,
  updateAccountInfo,
  resetPassword,
  logout,
  checkNewPhone,
  updatePhone,
} = accountStore;
const searchName = ref('');
const createBtnLoading = ref(false);
const emits = defineEmits({
  search: (searchName: string) => {
    return !!(searchName || searchName === '');
  },
});

onMounted(async () => {
  await getAccountInfo();
});

// 搜索白板
function search(e: Event) {
  if (e.type !== 'input') {
    emits('search', searchName.value);
  }
}

// 新建白板
async function createWhiteBoard() {
  createBtnLoading.value = true;
  try {
    const res = await operateWhiteBoard.createWhiteBoard({
      name: '未命名白板',
      teamId: teamStore.currentTeamId,
    });
    if (res?.code === 0) {
      boardStore.setCurrentBoardId(res.data);
      await router.push({ path: `/board/${boardStore.currentBoardId}` });
    }
    createBtnLoading.value = false;
  } catch (e) {
    createBtnLoading.value = false;
    console.error(e);
  }
}

// 退出登录
async function logoutAccount() {
  try {
    await logout();
    await router.push({ name: 'login' });
  } catch (e) {
    console.error(e);
  }
}

// 账户信息对话框数据
const accountInfoModal = reactive({
  infoModalVisible: false,
  isUpdatingNickname: false,
});
const nickNameInputRef = ref(null);

// 限制图片大小最大为5MB
const fileMaxSize = 4;
// 限制图片格式
const fileTypes = ['image/jpeg', 'image/jpg', 'image/png'];
// 自定义上传图片方法（上传头像）
async function uploadNewAvatar(e: any) {
  try {
    const size4MB = e.file.size / 1024 / 1024 <= fileMaxSize;
    const isImage = fileTypes.includes(e.file.type);
    if (!size4MB) {
      message.warning('上传图片大小不能超过4MB');
      return;
    }
    if (!isImage) {
      message.warning('上传图片只能是 JPG、JPEG、PNG 格式');
      return;
    }
    const formData = new FormData();
    formData.append('img', e.file);
    const res = await uploadImg(formData);
    if (res) {
      const response = await updateAccountInfo('', res);
      if (response?.msg === '操作成功') {
        await getAccountInfo();
        await teamStore.getTeamMemberList();
      }
      e.onSuccess();
    }
    e.onError();
  } catch (e) {
    console.error(e);
  }
}

let oldNickname: string;
// 修改昵称 交互
function updateNickname() {
  oldNickname = nickname.value;
  accountInfoModal.isUpdatingNickname = true;
}
function cancelUpdate() {
  nickname.value = oldNickname;
  accountInfoModal.isUpdatingNickname = false;
}
watchEffect(() => {
  if (nickNameInputRef.value) {
    nickNameInputRef.value.focus();
  }
});
// 确认修改昵称
async function confirmUpdateNickname() {
  try {
    if (nickname.value.length < 1 || nickname.value.length > 15) {
      message.warning('昵称不可为空，长度1-15位');
      return;
    }
    const res = await updateAccountInfo(nickname.value, '');
    if (res?.msg === '操作成功') {
      await getAccountInfo();
      accountInfoModal.isUpdatingNickname = false;
    } else {
      message.error('系统异常，修改昵称失败');
    }
  } catch (e) {
    console.error(e);
  }
}

const editModalData = reactive({
  modalVisible: false,
  modalTitle: '',
  pwFormData: {
    newPassword: '',
    checkPassword: '',
  },
  phoneFormData: {
    prefix: '86',
    newPhoneNum: '',
    verifyCode: '',
  },
});
// 设置密码 表单引用
const pwFormRef = ref(null);
// 换绑手机号码 表单引用
const phoneFormRef = ref(null);
function openEditModal(option: string) {
  editModalData.modalVisible = true;
  editModalData.modalTitle = option;
}
// 验证 二次密码 表单项规则
const validatePassword2 = async (_rule: Rule, value: string) => {
  if (value === '') {
    return Promise.reject('请确认密码');
  } else if (value !== editModalData.pwFormData.newPassword) {
    return Promise.reject('两次输入的密码不匹配');
  } else {
    return Promise.resolve();
  }
};
const pwFormRules: Record<string, Rule[]> = {
  newPassword: [
    {
      required: true,
      validator: validatePassword,
      trigger: ['change', 'blur'],
    },
  ],
  checkPassword: [
    {
      required: true,
      validator: validatePassword2,
      trigger: ['change', 'blur'],
    },
  ],
};
const phoneFormRules: Record<string, Rule[]> = {
  newPhoneNum: [{ validator: validateUsername, trigger: ['blur', 'change'] }],
  verifyCode: [{ validator: validateVerifyCode, trigger: ['blur', 'change'] }],
};
// 修改密码
function updatePassword() {
  pwFormRef.value
    ?.validate()
    .then(async (res: any) => {
      const response = await resetPassword(res.newPassword, res.checkPassword);
      if (response?.msg === '操作成功') {
        editModalData.modalVisible = false;
        message.success('密码修改成功，3秒后自动退出登录');
        setTimeout(async () => {
          await logoutAccount();
        }, 3000);
      }
    })
    .catch((e: Error) => {
      console.error(e);
    });
}

const verifyCodeBtn = reactive({
  text: '获取短信验证码',
  disabled: false,
  loading: false,
});
// 获取 短信验证码
async function getVerifyCode() {
  verifyCodeBtn.loading = true;
  phoneFormRef.value
    ?.validateFields(['newPhoneNum'])
    .then(async (res: any) => {
      // 获取短信验证码前 先验证新手机号码
      const res1 = await checkNewPhone(res.newPhoneNum);
      if (!res1?.data) {
        verifyCodeBtn.loading = false;
        message.error(res1?.msg);
        return;
      }
      // 验证新手机号码通过后才可以获取验证码
      const response = await operateAccount.getVerifyCode({
        phoneNum: res.newPhoneNum,
      });
      if (response.msg === '发送成功') {
        verifyCodeBtn.loading = false;
        message.success('验证码发送成功');
        // 获取成功后缓冲60s
        let timer = 60;
        verifyCodeBtn.disabled = true;
        verifyCodeBtn.text = '验证码（' + timer + 's）';
        const timeFun = setInterval(() => {
          --timer;
          verifyCodeBtn.text = '验证码（' + timer + 's）';
          if (timer == 0) {
            verifyCodeBtn.text = '获取短信验证码';
            verifyCodeBtn.disabled = false;
            clearInterval(timeFun);
          }
        }, 1000);
      }
      verifyCodeBtn.loading = false;
    })
    .catch((err: Error) => {
      verifyCodeBtn.loading = false;
      console.log(err);
    });
}
// 取消 显示修改表单
function cancelEdit() {
  pwFormRef.value?.resetFields();
  phoneFormRef.value?.resetFields();
  editModalData.modalVisible = false;
}
async function confirmUpdatePhone() {
  phoneFormRef.value
    ?.validate()
    .then(async (res: any) => {
      const response = await updatePhone(res.newPhoneNum, res.verifyCode);
      if (response?.msg === '操作成功') {
        editModalData.modalVisible = false;
        await getAccountInfo();
        message.success('手机号码换绑成功，3秒后自动退出登录');
        setTimeout(async () => {
          await logoutAccount();
        }, 3000);
      }
    })
    .catch((e: Error) => {
      console.error('校验失败', e);
    });
}
</script>

<style scoped lang="scss">
.p-workbench-main__header {
  height: 8%;
  padding: 1.2rem 3rem;
  background-color: #ffffff;
  .p-workbench-main__header-avatar {
    cursor: pointer;
    &:hover {
      box-shadow: 0 0 5px 0 rgba(192, 192, 192, 1);
    }
  }
}
.color-grey {
  color: #9a9a9a;
}
</style>
